當我們對函式使用 call, apply, bind 這三種方法時,能改變 this
的值
先來看一般的函式呼叫
var family = {
myName: 'weiwei',
};
function fn(para1, para2){
console.log(this, para1, para2);
};
fn(1, 2);
此時函式內的 this
是指向全域,這在昨天的文章有解釋
使用 call()
時,在 ()
中第一個要代入 this
的值,隨後才將參數代入
var family = {
myName: 'weiwei',
};
function fn(para1, para2){
console.log(this, para1, para2);
};
fn.call(family, 1, 2);
在範例中,我們將 this
指向 family
這個物件,
而 1
、 2
是做為參數代入函式中,
因此函式中的 this
會回傳 family
,
而 para1
、 para2
則分別回傳 1
、 2
,
apply()
中第一個參數也是帶入 this
的值,隨後使用 []
將函式的參數代入
var family = {
myName: 'weiwei',
};
function fn(para1, para2){
console.log(this, para1, para2);
};
fn.apply(family, [3, 4]);
該範例 this
是指向 family
這個物件,
而函式的參數 para1
、 para2
的值為 []
中的 3
、 4
,
使用上跟 call()
差不多
我們使用 bind()
時,我們會將它賦予到變數中,
而 ()
內第一個參數也是代入 this
的值,隨後代入函式的參數
var family = {
myName: 'weiwei',
};
function fn(para1, para2){
console.log(this, para1, para2);
};
var fn2 = fn.bind(family, 5, 6);
fn2();
在昨天的文章中有提到,當我們使用 Simple Call 時,this
會指向全域,
而範例中 fn2()
是因為在 bind()
中,就已經將 this
指向 family
物件,
因此在執行 fn2()
時,this
會指向 family
,
而此時我們也能將參數放到 fn2()
中
var family = {
myName: 'weiwei',
};
function fn(para1, para2){
console.log(this, para1, para2);
};
var fn2 = fn.bind(family);
fn2(7, 8);
一般來說 this
會以物件形式呈現,
而在非嚴謹模式下的函式中,
當我們在 call()
的第一個參數代入原始型別時,
則會將原始型別的值進行封裝,封裝後的型別為 object
,
但如果帶入 null
、 undefined
時,
則 this
會指向全域,這在 MDN 文件中有說明
function fn(para1, para2){
console.log(this, typeof this, para1, para2);
};
fn.call(1, 1, 2);
fn.call('weiwei', 1, 2);
fn.call(undefined, 1, 2);
以下列出嚴謹模式的特點
我們直接看範例
(function(){
'use strict'
a = 10;
})();
此執會看見 a is not defined
,
在嚴謹模式下會要求你先宣告變數,才能做賦予值的動作
當我們拿掉 'use strict'
時,則不會出錯
(function(){
a = 10;
})();
接著我們在函式中加入 'use strict'
,使用 call()
看結果如何
function fn(para1, para2){
'use strict';
console.log(this, typeof this, para1, para2);
};
fn.call(1, 1, 2);
此時能看見在嚴謹模式下,如果 this
代入原始型別,其值不會被改為建構式,
那如果我們代入 undefined
會如何呢?
function fn(para1, para2){
'use strict';
console.log(this, typeof this, para1, para2);
};
fn.call(undefined, 7, 8);
此時 this
的值會是 undefined
,而在非嚴謹模式下會指向全域,
接著我們使用簡易呼叫來看 this
的值會如何
function fn(para1, para2){
'use strict';
console.log(this, typeof this, para1, para2);
};
fn(9, 'weiwei');
在非嚴謹模式中函式的 this
是指向全域,
但此時能看見在嚴謹模式下函式的 this
為 undefined
而我們使用簡易呼叫時,概念跟使用 call()
很像,
只差別在簡易呼叫不會傳入 this
的值,此時的 this
就會是 undefined
,
因此我們我可以知道 this
的本質是 undefined
,
所以一般不太建議使用簡易呼叫中的 this
,
關於更多嚴謹模式的說明可到MDN 文件查看
以上是今天 call, apply, bind 與嚴謹模式的內容,感謝觀看!!